/*
 * Copyright 2004 original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jbfilter.impl;

import java.util.Date;

import org.apache.commons.lang.time.DateUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.jbfilter.core.JbfilterComparatorKeyword;
import org.jbfilter.core.TruncateUnit;
import org.jbfilter.core.fcomps.single.DateFilterComponent;

class _DateFilterComponentHibernateSupport<E, C extends DateFilterComponent<E>>
	extends
		_CompareFilterComponentHibernateSupport<E, Date, C> {

	_DateFilterComponentHibernateSupport(C filterComponent) {
		super(filterComponent);
	}

	@Override
	protected Criterion buildCriterionCallBackFromSFCSupport(String propertyPath, Date value) {
		DateFilterComponent<E> dfComp = getFilterComponent();
		JbfilterComparatorKeyword comparatorKeyword = dfComp.getComparatorKeyword();
		TruncateUnit truncate = dfComp.getTruncate();
		if (truncate != null) {
			int calConst = truncate.getCalConst();
			
			Date startDateToTest;
			Date endDateToTest;
			Criterion startCriterion;
			Criterion endCriterion;
			Criterion criterion;

			switch (comparatorKeyword) {
			case eq:
				startDateToTest = DateUtils.truncate(value, calConst);
				endDateToTest = _JbFilterDateUtils.add(value, calConst, 1);
				endDateToTest = DateUtils.truncate(endDateToTest, calConst);
				startCriterion = Restrictions.ge(propertyPath, startDateToTest);
				endCriterion = Restrictions.lt(propertyPath, endDateToTest);
				criterion = Restrictions.and(startCriterion, endCriterion);
				return criterion;
			case lt:
				endDateToTest = DateUtils.truncate(value, calConst);
				return Restrictions.lt(propertyPath, endDateToTest);
			case le:
				endDateToTest = _JbFilterDateUtils.add(value, calConst, 1);
				endDateToTest = DateUtils.truncate(endDateToTest, calConst);
				return Restrictions.le(propertyPath, endDateToTest);
			case gt:
				startDateToTest = DateUtils.truncate(value, calConst);
				startDateToTest = _JbFilterDateUtils.add(value, calConst, 1);
				return startCriterion = Restrictions.ge(propertyPath, startDateToTest);
			case ge:
				startDateToTest = DateUtils.truncate(value, calConst);
				return startCriterion = Restrictions.ge(propertyPath, startDateToTest);
			default :
				throw new AssertionError("bug : treat missing keyword.");	
			}
		} else {
			switch (comparatorKeyword) {
			case eq:
				return Restrictions.eq(propertyPath, value);
			case lt:
				return Restrictions.lt(propertyPath, value);
			case le:
				return Restrictions.le(propertyPath, value);
			case gt:
				return Restrictions.gt(propertyPath, value);
			case ge:
				return Restrictions.ge(propertyPath, value);
			default :
				throw new AssertionError("bug : treat missing keyword.");	
			}
		}
	}
}
